; In order to keep things simple, we will consider a very simple symbolic-differentiation program that handles expressions that are built up using only the operations of addition and multiplication with two arguments. Differentiation of any such expression can be carried out by applying the following reduction rules:

; Observe that the latter two rules are recursive in nature. That is, to obtain the derivative of a sum we first find the derivatives of the terms and add them. Each of the terms may in turn be an expression that needs to be decomposed. Decomposing into smaller and smaller pieces will eventually produce pieces that are either constants or variables, whose derivatives will be either 0 or 1.

; To embody these rules in a procedure we indulge in a little wishful thinking, as we did in designing the rational-number implementation. If we had a means for representing algebraic expressions, we should be able to tell whether an expression is a sum, a product, a constant, or a variable. We should be able to extract the parts of an expression. For a sum, for example we want to be able to extract the addend (first term) and the augend (second term). We should also be able to construct expressions from parts. Let us assume that we already have procedures to implement the following selectors, constructors, and predicates:

; (variable? e) 	;Is e a variable?
; (same-variable? v1 v2) ;	Are v1 and v2 the same variable?

; (sum? e)
; 	; Is e a sum?
; (addend e) 	;Addend of the sum e.
; (augend e) 	Augend of the sum e.
; (make-sum a1 a2) 	Construct the sum of a1 and a2.

; (product? e)
; 	Is e a product?
; (multiplier e) 	Multiplier of the product e.
; (multiplicand e) 	Multiplicand of the product e.
; (make-product m1 m2) 	Construct the product of m1 and m2.
; Using these, and the primitive predicate number?, which identifies numbers, we can express the differentiation rules as the following procedure:

(define (deriv exp var)
  (cond ((number? exp) 0)
        ((variable? exp)
         (if (same-variable? exp var) 1 0))
        ((sum? exp)
         (make-sum (deriv (addend exp) var)
                   (deriv (augend exp) var)))
        ((product? exp)
         (make-sum
           (make-product (multiplier exp)
                         (deriv (multiplicand exp) var))
           (make-product (deriv (multiplier exp) var)
                         (multiplicand exp))))
        (else
         (error "unknown expression type -- DERIV" exp))))

; This deriv procedure incorporates the complete differentiation algorithm. Since it is expressed in terms of abstract data, it will work no matter how we choose to represent algebraic expressions, as long as we design a proper set of selectors and constructors. This is the issue we must address next.

; Representing algebraic expressions

; We can imagine many ways to use list structure to represent algebraic expressions. For example, we could use lists of symbols that mirror the usual algebraic notation, representing ax + b as the list (a * x + b). However, one especially straightforward choice is to use the same parenthesized prefix notation that Lisp uses for combinations; that is, to represent ax + b as (+ (* a x) b). Then our data representation for the differentiation problem is as follows:

;     The variables are symbols. They are identified by the primitive predicate symbol?:

    (define (variable? x) (symbol? x))

    ; Two variables are the same if the symbols representing them are eq?:

    (define (same-variable? v1 v2)
      (and (variable? v1) (variable? v2) (eq? v1 v2)))

    ; Sums and products are constructed as lists:

    (define (make-sum a1 a2) (list '+ a1 a2))

    (define (make-product m1 m2) (list '* m1 m2))

    ; A sum is a list whose first element is the symbol +:

    (define (sum? x)
      (and (pair? x) (eq? (car x) '+)))

    ; The addend is the second item of the sum list:

    (define (addend s) (cadr s))

    ; The augend is the third item of the sum list:

    (define (augend s) (caddr s))

    ; A product is a list whose first element is the symbol *:

    (define (product? x)
      (and (pair? x) (eq? (car x) '*)))

    ; The multiplier is the second item of the product list:

    (define (multiplier p) (cadr p))

    ; The multiplicand is the third item of the product list:

    (define (multiplicand p) (caddr p))